package com.frame.demo.mvp;

import com.frame.demo.rest.ExceptionDispose;
import com.frame.demo.rest.RestError;
import com.frame.demo.exception.ExceptionUtil;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;

/**
 * Created by lei on 2017/9/8.
 */

public abstract class BaseObserver<T> implements Observer<T> {
    private BasePresenter mBasePresenter;
    private boolean mIsShowLoadingDlg;

    public BaseObserver(BasePresenter basePresenter) {
        this.mBasePresenter = basePresenter;
        if (!mBasePresenter.isViewAttached()) return;
        this.mBasePresenter.getMvpView().onShowLoadingDialog();
    }

    public BaseObserver(BasePresenter pBasePresenter, boolean isShowLoadingDlg) {
        this.mBasePresenter = pBasePresenter;
        this.mIsShowLoadingDlg = isShowLoadingDlg;
        if (!mBasePresenter.isViewAttached()) return;
        if (isShowLoadingDlg) {
            this.mBasePresenter.getMvpView().onShowLoadingDialog();
        }
    }


    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onNext(T value) {
        if (!mBasePresenter.isViewAttached()) return;
        doOnNext(value);
    }

    protected abstract void doOnNext(T value);

    @Override
    public void onError(Throwable e) {
        if (!mBasePresenter.isViewAttached()) return;
        BaseView _mvpView = this.mBasePresenter.getMvpView();
        _mvpView.onDismissLoadingDialog();
        RestError _restError = ExceptionUtil.gennerateRestError(e);
        //踢下线和非官方版本也不下发
        if ((_restError.getCode() == ExceptionDispose.EXCEPTION_VALIDITY ||
                _restError.getCode() == ExceptionDispose.EXCEPTION_TICK_OUT)) {
            _mvpView.onExceptionDispose(_restError);
            return;
        }
        if (!onFailed(_restError)) {
            _mvpView.onExceptionDispose(_restError);
        }
    }

    @Override
    public void onComplete() {
        if (!mBasePresenter.isViewAttached()) return;
        this.mBasePresenter.getMvpView().onDismissLoadingDialog();
    }

    /**
     * 此方法只处理：当请求失败时，与业务相关的处理。同时dismiss Dialog也不需要在这里处理
     *
     * @param pRestError
     * @return true:表未异常不需要上层再处理(即不需要再回调onExceptionDisponse方法)
     * false :此异常需要基类中的异常处理方案处理。（表示此异常没有被消费掉）
     */
    public abstract boolean onFailed(RestError pRestError);
}
